package com.company.pangu.aliyun.sms.client;

import cn.hutool.core.util.ObjectUtil;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.*;
import com.aliyun.teaopenapi.models.Config;
import com.company.nuwa.common.utils.JsonUtils;
import com.company.pangu.aliyun.sms.config.SmsConfig;
import com.company.pangu.aliyun.sms.constants.SmsConstants;
import com.company.pangu.aliyun.sms.request.SmsSendRequest;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>阿里云短信服务</p >
 *
 * @author Nikola Tesla
 * @version 1.0
 * @date 2020/09/25 11:48
 */
@Slf4j
public class SmsClient {

    private final Client client;

    public SmsClient(SmsConfig smsConfig) {
        this.client = createClient(smsConfig);
    }

    /**
     * 发送短信
     * <p>
     * https://next.api.aliyun.com/api/Dysmsapi/2017-05-25/SendSms?params={}
     *
     * @param req 短信请求体
     * @throws RuntimeException 短信发送失败
     */
    public void send(SmsSendRequest req) {
        SendSmsRequest request = new SendSmsRequest()
                .setPhoneNumbers(req.getPhoneNumbers())
                .setSignName(req.getSignName())
                .setTemplateCode(req.getTemplateCode())
                .setTemplateParam(req.getTemplateParam());
        try {
            SendSmsResponse response = client.sendSms(request);
            log.info("sms send request={}, response={}", JsonUtils.objectToJson(request), JsonUtils.objectToJson(response));

            if (success(response.getBody().getCode())) {
                return;
            }
        } catch (Exception e) {
            log.error("sms send has error", e);
        }
        throw new RuntimeException("sms send has error");
    }

    /**
     * 校验短信签名，只判断 resp data 中 code 是否为 OK
     * <p>
     * https://next.api.aliyun.com/api/Dysmsapi/2017-05-25/QuerySmsSign?params={}
     *
     * @param signName 短信签名
     * @throws RuntimeException 检测失败时报错
     */
    public void checkSign(String signName) {
        try {
            QuerySmsSignRequest request = new QuerySmsSignRequest();
            request.setSignName(signName);
            QuerySmsSignResponse response = client.querySmsSign(request);
            log.info("sms check sign request={}, response={}", JsonUtils.objectToJson(request), JsonUtils.objectToJson(response));

            if (success(response.getBody().getCode())) {
                return;
            }
        } catch (Exception e) {
            log.error("check sign error", e);
        }
        throw new RuntimeException("sms signature illegal");
    }

    /**
     * 校验模板，只判断 resp data 中 code 是否为 OK
     * <p>
     * https://next.api.aliyun.com/api/Dysmsapi/2017-05-25/QuerySmsTemplate?params={}
     *
     * @param templateCode 短信模板
     * @return 模板内容
     * @throws RuntimeException 检测失败时报错
     */
    public String checkTemplate(String templateCode) {
        try {
            QuerySmsTemplateRequest request = new QuerySmsTemplateRequest();
            request.setTemplateCode(templateCode);
            QuerySmsTemplateResponse response = client.querySmsTemplate(request);
            log.info("sms query template request={}, response={}", JsonUtils.objectToJson(request), JsonUtils.objectToJson(response));

            if (success(response.getBody().getCode())) {
                return response.getBody().getTemplateContent();
            }

            throw new RuntimeException("sms template illegal");
        } catch (Exception e) {
            log.error("query sms template has error", e);
            throw new RuntimeException("sms template illegal");
        }
    }

    /**
     * 使用AK&SK初始化账号Client
     *
     * @param smsConfig
     * @return
     */
    @SneakyThrows
    private com.aliyun.dysmsapi20170525.Client createClient(SmsConfig smsConfig) {
        String endPoint = ObjectUtil.defaultIfEmpty(smsConfig.getEndPoint(), "dysmsapi.aliyuncs.com");
        Config config = new Config()
                // 您的AccessKey ID
                .setAccessKeyId(smsConfig.getAccessKeyId())
                // 您的AccessKey Secret
                .setAccessKeySecret(smsConfig.getAccessKeySecret())
                // 访问的域名
                .setEndpoint(endPoint);
        return new com.aliyun.dysmsapi20170525.Client(config);
    }

    private boolean success(String code) {
        return SmsConstants.SUCCESS.equalsIgnoreCase(code);
    }

}
